home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / c_lib01.arc / CFLOW.C next >
Text File  |  1985-07-21  |  9KB  |  321 lines

  1.  
  2. /*
  3. **   CFLOW.C : find module call structure of c program
  4. **   refer to cflow.doc for how to use
  5. **                                       Mark Ellington
  6. **                                       05-27-84
  7. */
  8.  
  9. /*
  10. **    Modified for Lattice C.
  11. **    Changed logic in skipline() to correct problem with '#'.
  12. **    Changed logic in comout() to correct problem with '/'.
  13. **                                       Lew Paper
  14. **                                       7/21/85
  15. */
  16.  
  17. #include <stdio.h>
  18.  
  19. #define LINS 256
  20.  
  21. FILE *fptr;       /* input file pointer */ 
  22. int level;      /* keep track of level of open "{"s */
  23. char name[100]; /* module name buffer */
  24.  
  25. char ins[LINS];  /* source input line buffer */
  26. int curchar;     /* current character in input line buffer
  27.                    array subscript */    
  28.  
  29. main(argc,argv)
  30. int argc; char *argv[];
  31. {
  32.  
  33.         printf("\nCFLOW --> function declarations and calls in C source");
  34.         printf("\n by Mark Ellington"); 
  35.  
  36.         if (argc != 2) {
  37.                 printf("\nusage: cflow [infilename.ext] "); 
  38.                 exit();
  39.         }
  40.  
  41.         if ((fptr = fopen(argv[1],"r")) == FALSE) {
  42.                 printf("\nCan't open %s\n",argv[1]);
  43.                 exit();
  44.         }
  45.  
  46.         printf("\nSource file: %s",argv[1]);
  47.  
  48.         modules(); 
  49.  
  50.         fclose(fptr);
  51.         exit();
  52. }
  53.  
  54.  
  55. modules()    /* find function declarations and calls */
  56. {
  57.         int j;
  58.         char c;
  59.         int incom;       /* comment flag */
  60.         int decl;        /* module declaration line flag */
  61.         char *lastlin;   /* Pointer to ins if not last line and no error */
  62.                          /* NULL if error or last line */
  63.         int quoted;      /* within " quotes */
  64.         int header;      /* within function header (before 1st '{') */
  65.  
  66.         incom = quoted  = header = FALSE;
  67.  
  68.         lastlin = NULL;
  69.         
  70.         level = 0;
  71.  
  72.         do {
  73.  
  74.                 lastlin = fgets(ins, LINS, fptr);    /* read a line of source */
  75.                 
  76.                 decl = FALSE;  /* assume nothing */
  77.                 curchar = 0;
  78.                 while (curchar < LINS) {/* read for significant characters */
  79.  
  80.                         if (skipline()) break;
  81.  
  82.                         quotes();        /* skip single quoted character */
  83.  
  84.                         incom = comment(incom);  /* true if in comment */
  85.  
  86.                         c = ins[curchar];
  87.                 
  88.                         /* read for significant characters */
  89.  
  90.                         if (!incom) {
  91.  
  92.                                 /* skip double quoted strings */
  93.                         
  94.                                 if (c == '\042') quoted = !quoted;
  95.                                 
  96.                                 if (!quoted) {
  97.                         
  98.                                     switch(c) { 
  99.  
  100.                                         case '{' :       
  101.                                                 level++;
  102.                                                 header = FALSE;
  103.                                                 break;
  104.  
  105.                                         case '}' :       
  106.                                                 level--;
  107.                                                 break;   
  108.  
  109.                                         /* "(" always follows function call */
  110.                                         /* or declaration */
  111.                         
  112.                                         case '(' :       
  113.  
  114.                                         if (!ischar(ins[curchar-1])) 
  115.                                                 break;
  116.                                         lookbak(curchar);
  117.                                         j = modname();
  118.                                         if (!j) break;
  119.                                         else decl = TRUE;
  120.                                         if (j == 2) 
  121.                                                 header = TRUE;   
  122.                                         break;
  123.  
  124.  
  125.                                         default : 
  126.                                                   break;
  127.                                     }
  128.                                 }
  129.                         }
  130.                 
  131.                         ++curchar;     /* next character */
  132.                 }
  133.                 
  134.                 /* display argument declarations */
  135.                 comout(ins);                     
  136.                 if (header && !decl) printf("%s",ins);
  137.  
  138.         } while (lastlin != NULL);    /* = NULL if last line */
  139.  
  140. }
  141.  
  142. /* skip this line ? */
  143.  
  144. skipline()
  145. {
  146. char c;
  147. int sk; /* Return value for function */
  148.  
  149.         c = ins[curchar];
  150.  
  151.         if (c == '\0') return(TRUE);     /* end of line */
  152.  
  153.         sk = FALSE;  /* No except for macro defines */
  154.         
  155.         if (c == '#') {              /* skip macro defs */
  156.                 if (curchar < 5) /* at beginning of line */
  157.                         sk = (!strcmp("define",&ins[curchar+1]));
  158.         }
  159.  
  160.         return(sk);
  161.  
  162. }
  163.  
  164.  
  165. /* skip characters quoted (for instance '}' would throw off level count */
  166.  
  167. quotes()
  168. {  
  169.         if (flowchar(ins[curchar]))          /* test critical chars only */
  170.             if (ins[curchar+1] == '\047')   /* next char single quote? */
  171.                 if (curchar+2 < LINS)         /* don't pass end of string */
  172.                         curchar = curchar + 2; /* skip past quote */
  173. }
  174.  
  175.  
  176. /* return TRUE if entering comment, FALSE if exiting */
  177.  
  178. comment(incom)
  179. int incom;
  180. {
  181.         if (ins[curchar] == '/') {
  182.                 if (ins[curchar+1] == '*') {
  183.                          if (curchar + 1 < LINS)   /* stay within string */ 
  184.                               return(TRUE);
  185.                          else return(incom);  /* unchanged */
  186.                 }
  187.                 else if (ins[curchar-1] == '*') {
  188.                         if(curchar - 1 >= 0)  /* stay within string */
  189.                                 return(FALSE);
  190.                         else return(incom);  /* unchanged */
  191.                 }
  192.                 else return(incom); /* An isolated slash, so unchanged */
  193.         }
  194.         else return(incom);  /* unchanged */
  195. }
  196.  
  197.  
  198. /* look back from position n in string.  called with n indicating '('.
  199.    determine function name  */
  200.  
  201. lookbak(n)
  202. int n;
  203. {
  204.         int i;
  205.  
  206.         while (!ischar(ins[n])) {
  207.                 if (n == 0) break;
  208.                 --n;
  209.         }
  210.  
  211.         /* find leading blank */
  212.         while (ischar(ins[n-1])) {
  213.                 if (n == 0) break;
  214.                 --n;
  215.         }
  216.  
  217.         /* save name */
  218.         /* include variable declarations if module declaration */
  219.  
  220.         i = 0;
  221.         if (level == 0) {
  222.                 while (ins[n])               /* full line if declaration */
  223.                         name[i++] = ins[n++];
  224.         }
  225.         else {
  226.                 while (ischar(ins[n]))      /* function call within function */
  227.                         name[i++] = ins[n++];
  228.         }
  229.  
  230.         name[i] = '\0';
  231.  
  232.         comout(name);    /* remove comment from name string */
  233.                 
  234. }
  235.  
  236.  
  237. /* terminate string at comment */
  238.  
  239. comout(s)
  240. char *s;
  241. {
  242. char c;  
  243.         
  244.         while(c = *s++) 
  245.                 if (c == '/')
  246.                         if (*s == '*') {
  247.                                 --s;
  248.                                 *s++ = '\n';
  249.                                 *s = '\0';
  250.                                 break;
  251.                         }
  252.  
  253. }
  254.  
  255.  
  256.  
  257. /* display module name with indentation according to { level */
  258. /* returns 0 if not module, 1 if call within module, 2 if    */
  259. /* module declaration  */
  260.  
  261. modname()
  262. {
  263.         int j;
  264.  
  265.         if (unreserved()) {              /* test if builtin like while */
  266.                 if (level == 0) {
  267.                         printf("\n\n\n");
  268.                         printf("**\n");
  269.                         comout(ins);
  270.                         printf("%s",ins);
  271.                         return(2);
  272.                 }
  273.                 else {
  274.                         printf("\n");
  275.                         for (j=0; j < level; ++j) 
  276.                                 putchar('\t');
  277.                         printf("%s()",name);
  278.                         return(1);
  279.                 }
  280.         }
  281.         return(0);
  282.         
  283. }
  284.  
  285. /* test for names that are operators not functions */
  286.  
  287. unreserved()
  288. {
  289.  
  290.         if (!strcmp(name,"return")) return(0);
  291.         else if (!strcmp(name,"if")) return(0);
  292.         else if (!strcmp(name,"while")) return(0);
  293.         else if (!strcmp(name,"for")) return(0);
  294.         else if (!strcmp(name,"switch")) return(0);
  295.  
  296.         else return(1);
  297.  
  298. }
  299.  
  300.  
  301. /* test if character is one that program tracks */
  302.  
  303. flowchar(c)
  304. char c;
  305. {
  306.         if (c == '{' || c == '}' || c == '\"') return(TRUE);
  307.         else return(FALSE);
  308.         
  309.  
  310.  
  311. /* test for character */
  312.  
  313. ischar(c)
  314. char c;
  315. {
  316.         if (isalpha(c) || isdigit(c)) return(TRUE);
  317.         else return(FALSE);
  318. }
  319.  
  320.